package com.camus.verify.biz.impl;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StopWatch;

import com.camus.verify.biz.MatchBiz;
import com.camus.verify.biz.MatchHandler;
import com.camus.verify.bo.MatchBO;
import com.camus.verify.bo.SpecWithPrice;
import com.camus.verify.entity.VerifyTask;
import com.camus.verify.entity.VerifyTaskAp;
import com.camus.verify.entity.VerifyTaskInvoice;
import com.camus.verify.service.IVerifyResultApService;
import com.camus.verify.service.IVerifyResultService;
import com.camus.verify.service.IVerifyResultInvoiceService;
import com.camus.verify.service.IVerifyTaskApService;
import com.camus.verify.service.IVerifyTaskInvoiceService;

import cn.hutool.json.JSONUtil;

@Service
public class MatchBizImpl implements MatchBiz {

	private static final Logger log = LoggerFactory.getLogger(MatchBizImpl.class);

	@Autowired
	private List<MatchHandler> matchHandlers;
	@Autowired
	private IVerifyResultService resultService;
	@Autowired
	private IVerifyResultApService resultApService;
	@Autowired
	private IVerifyResultInvoiceService resultInvoiceService;
	@Autowired
	private IVerifyTaskApService taskApService;
	@Autowired
	private IVerifyTaskInvoiceService taskInvoiceService;
	@Autowired
	private TransactionTemplate transactionTemplate;

	@Override
	public void match(SpecWithPrice matchDim, final VerifyTask task, final List<VerifyTaskAp> apList,
			final List<VerifyTaskInvoice> invoiceList) {
		StopWatch sw = new StopWatch(JSONUtil.toJsonStr(matchDim));
		for (MatchHandler matchHandler : matchHandlers) {
			sw.start(matchHandler.getMatchHandlerName());
			List<MatchBO> matchBOList = matchHandler.match(task, invoiceList, apList);
			sw.stop();
			if (CollectionUtils.isNotEmpty(matchBOList)) {
				sw.start("保存匹配结果");
				// 标记为已匹配，避免下个matchHandler重复匹配
				matchBOList.stream().flatMap(t -> t.getTaskApList().stream()).forEach(t -> {
					t.setMatched(1);
				});
				matchBOList.stream().flatMap(t -> t.getTaskInvoiceList().stream()).forEach(t -> {
					t.setMatched(1);
				});

				transactionTemplate.executeWithoutResult(status -> {
					// 保存核销结果
					resultService.saveBatch(matchBOList.stream().map(MatchBO::getResult).collect(Collectors.toList()));
					resultInvoiceService.saveBatch(matchBOList.stream().flatMap(t -> t.getInvoiceList().stream())
							.collect(Collectors.toList()));
					resultApService.saveBatch(
							matchBOList.stream().flatMap(t -> t.getApList().stream()).collect(Collectors.toList()));

					// 回写核销数据源
					taskApService.updateMatchedBatchByIds(matchBOList.stream().flatMap(t -> t.getTaskApList().stream())
							.map(VerifyTaskAp::getPkid).collect(Collectors.toList()));
					taskInvoiceService
							.updateMatchedBatchByIds(matchBOList.stream().flatMap(t -> t.getTaskInvoiceList().stream())
									.map(VerifyTaskInvoice::getPkid).collect(Collectors.toList()));
				});
				sw.stop();
			}
		}
		log.info(sw.prettyPrint());
	}

}
